<header>
    JavaScript
</header>
<h2>
    JS 数据类型 ?存储上的差别
</h2>
<p>
    数据类型主要包括两部分：
</p>
<ul>
    <li>
        基本数据类型： Undefined、Null、Boolean、Number 和 String，Symbol(创建后独一无二且不可变的数据类型 )
    </li>
    <li>
        引用数据类型： Object (包括 Object 、Array 、Function)
    </li>
</ul>
<p>
    存储区别：
</p>
<ul>
    <li>
        基本数据类型存储在栈中
    </li>
    <li>
        引用类型的对象存储于堆中
    </li>
</ul>
<h2>
    事件队列（宏任务微任务）
</h2>
<p>
    微任务一般比宏任务先执行，并且微任务队列只有一个，宏任务队列可能有多个。另外我们常见的点击和键盘等事件也属于宏任务。
</p>
<h3>
    宏任务队列（Macrotask Queue）
</h3>
<ul>
    <li>
        setTimeout/setInterval
    </li>
    <li>
        I/O操作
    </li>
    <li>
        UI渲染
    </li>
    <li>
        script整体代码
    </li>
</ul>
<h3>
    微任务队列（Microtask Queue）
</h3>
<ul>
    <li>
        Promise.then/catch/finally
    </li>
    <li>
        MutationObserver
    </li>
    <li>
        queueMicrotask
    </li>
</ul>
<h3>
    事件循环运行流程
</h3>
<ol>
    <li>
        执行同步代码直至调用栈清空
    </li>
    <li>
        执行所有微任务直至微任务队列清空
    </li>
    <li>
        执行一个宏任务
    </li>
    <li>
        重复步骤1-3
    </li>
</ol>
<h2>
    防抖节流
</h2>
<p>
    节流： 如果这个事件会被频繁触发，那么节流函数会按照一定的频率来执行函数，不管在这个中间有多少次触发这个事件，执行函数的频次总是固定的；
</p>
<p>
    防抖： 当事件触发时，相应的函数并不会立即触发，而是会等待一定的时间(非常短的时间)，当事件密集触发时，函数的触发会被频繁的推迟，只有等待了一段时间也没有事件触发，才会真正的执行响应函数。
</p>
<h2>
    for…in 和 for … of区别
</h2>
<p>
    for…in 循环是用来遍历对象属性的，它可以枚举目标对象的所有可枚举属性，包括继承链上的属性，但遍历的顺序是不确定的。
</p>
<p>
    for…of 循环是用来遍历可迭代对象 (Iterable) 的，它可以遍历数组、字符串、Map、Set 等内置的可迭代对象，但不能遍历普通的对象，也不能遍历对象的属性。
</p>